//
//  LineNode.m
//  HKOCRuler
//
//  Created by lbxia on 2018/11/23.
//  Copyright © 2018年 lbx. All rights reserved.
//

#import "LineNode.h"
#import "Utilities.h"

@implementation LineNode

- (instancetype)initWithStartPos:(SCNVector3)startpos sceneV:(ARSCNView*)sceneV cameraNode:(SCNNode*)cameraNode
{
    if (self = [super init]) {
        
        self.sceneView = sceneV;
        
        SCNSphere *dot = [SCNSphere sphereWithRadius:1];
        dot.firstMaterial.diffuse.contents = [UIColor redColor];
        dot.firstMaterial.lightingModelName =  SCNLightingModelConstant;
        dot.firstMaterial.doubleSided = YES;
        
        self.startNode = [SCNNode nodeWithGeometry:dot];
        self.startNode.scale = SCNVector3Make(1/300., 1/300., 1/300.);
        self.startNode.position = startpos;
        [self.sceneView.scene.rootNode addChildNode:self.startNode];
        
        self.endNode = [SCNNode nodeWithGeometry:dot];
        self.endNode.scale = self.startNode.scale;
        
        self.lineNode = nil;
        
        SCNText *text = [SCNText textWithString:@"--" extrusionDepth:0.1];
        text.font = [UIFont systemFontOfSize:10];
        text.firstMaterial.diffuse.contents = [UIColor yellowColor];
        text.alignmentMode = kCAAlignmentCenter;
        text.truncationMode = kCATruncationMiddle;
        text.firstMaterial.doubleSided = YES;
        
        self.textNode = [SCNNode nodeWithGeometry:text];
        self.textNode.scale = SCNVector3Make(1/500.,1/500., 1/500.);
        self.textNode.eulerAngles = SCNVector3Make(0, M_PI, 0);
        
        self.textWrapNode = [[SCNNode alloc]init];
        [self.textWrapNode addChildNode:self.textNode];
        
        SCNLookAtConstraint *constraint = [SCNLookAtConstraint lookAtConstraintWithTarget:cameraNode];
        constraint.gimbalLockEnabled = YES;
        self.textWrapNode.constraints = @[constraint];
    }
    return self;
}

- (void)dealloc
{
    [self removeFromParent];
}

- (NSMutableArray<SCNVector3OBJ*>*)recentFocusSquarePositions
{
    if (!_recentFocusSquarePositions) {
        _recentFocusSquarePositions = [NSMutableArray array];
    }
    return _recentFocusSquarePositions;
}

- (CGFloat)segmentLength
{
    SCNVector3 posStart = _startNode.position;
    SCNVector3 posEnd = _endNode.position;
    
    CGFloat length = [Utilities distanceFromPos:posStart to:posEnd];
    //厘米
    return  length * 100;
}

- (CGFloat)updatePosition:(SCNVector3)pos camera:(ARCamera*)camera
{
    if (!camera) {
        return 0;
    }
    
    SCNVector3 posEnd = [self updateTransformForPosition:pos camera:camera];
    
    if (_endNode.parentNode == nil) {
        [_sceneView.scene.rootNode addChildNode:_endNode];
    }
    _endNode.position = pos;
    
    SCNVector3 posStart = _startNode.position;
    
    SCNVector3 middle = SCNVector3Make((posStart.x+posEnd.x)/2.0, (posStart.y+posEnd.y)/2.0 + 0.010, (posStart.z+posEnd.z)/2.0);
    
    //可能有问题？
    SCNText *text = (SCNText*)_textNode.geometry;
    CGFloat length = [self segmentLength];
    
    text.string = [NSString stringWithFormat:@"(%d): %.2fcm",_idx,length];
//    _textNode setPivot:<#(SCNMatrix4)#>
    

    SCNVector3 minVec;
    SCNVector3 maxVec;
    [_textNode getBoundingBoxMin:&minVec max:&maxVec];
    SCNVector3 bound = SCNVector3Make( maxVec.x - minVec.x, maxVec.y - minVec.y, maxVec.z - minVec.z);
    [_textNode setPivot:SCNMatrix4MakeTranslation(bound.x / 2, bound.y, bound.z / 2)];
    _textWrapNode.position = middle;
    
    if (_textWrapNode.parentNode == nil) {
        [_sceneView.scene.rootNode addChildNode:_textWrapNode];
    }
    
    [_lineNode removeFromParentNode];
    _lineNode = [self lineBetweenNodeA:_startNode nodeB:_endNode];
    [_sceneView.scene.rootNode addChildNode:_lineNode];
    
    return length;
}

- (void)removeFromParent
{
    [_startNode removeFromParentNode];
    [_endNode removeFromParentNode];
    [_lineNode removeFromParentNode];
    [_textWrapNode removeFromParentNode];
}

- (SCNNode*)lineBetweenNodeA:(SCNNode*)nodeA nodeB:(SCNNode*)nodeB
{

    Float32 positions[] =
    {nodeA.position.x,nodeA.position.y,nodeA.position.z,
        nodeB.position.x,nodeB.position.y,nodeB.position.z};
    NSData *positionData = [NSData dataWithBytes:positions length:sizeof(Float32)*6];
    
    int32_t indices[] = {0,1};
    NSData *indexData = [NSData dataWithBytes:indices length:sizeof(int32_t)*2];
    
    
    
    SCNGeometrySource *source = [SCNGeometrySource geometrySourceWithData:positionData semantic:SCNGeometrySourceSemanticVertex vectorCount:2 floatComponents:YES componentsPerVector:3 bytesPerComponent:sizeof(Float32) dataOffset:0 dataStride:sizeof(Float32)*3];
    
    SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:indexData primitiveType:SCNGeometryPrimitiveTypeLine primitiveCount:2 bytesPerIndex:sizeof(int32_t)];
    
    SCNGeometry *line = [SCNGeometry geometryWithSources:@[source] elements:@[element]];
    
    return [SCNNode nodeWithGeometry:line] ;
}



- (SCNVector3)updateTransformForPosition:(SCNVector3)position camera:(ARCamera*)camera
{
    [self.recentFocusSquarePositions addObject:[SCNVector3OBJ objectWith:position]];
    
    //数量超过8，将最早的部分删除掉，不超过8，不用处理
    if (self.recentFocusSquarePositions.count > 8) {
        NSInteger del = self.recentFocusSquarePositions.count - 8;
        NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndexesInRange: NSMakeRange(0, del)];
        [self.recentFocusSquarePositions removeObjectsAtIndexes:indexSet];
    }
    
    if (camera) {
        
        CGFloat tilt = fabsf(camera.eulerAngles.x);
        CGFloat threshold1 = M_PI / 2 * 0.65;
        CGFloat threshold2 = M_PI / 2 * 0.75;
        CGFloat yaw = atan2(camera.transform.columns[0].x, camera.transform.columns[1].x);
        
        CGFloat angle = 0;
      
        if (0 <= tilt < threshold1) {
            angle = camera.eulerAngles.y;
        }
        else if (threshold1 <= tilt < threshold2)
        {
            CGFloat relativeInRange = fabs((tilt - threshold1) / (threshold2 - threshold1));
            CGFloat normalizedY = [self normalizeWithAngle:camera.eulerAngles.y ref:yaw];
            
            angle = normalizedY * (1 - relativeInRange) + yaw * relativeInRange;
        }
        else
        {
            angle = yaw;
        }
    }
    
    //计算平均值
    SCNVector3 total = SCNVector3Make(0, 0, 0);
    for (SCNVector3OBJ *obj in self.recentFocusSquarePositions) {
        
        total.x += obj.x;
        total.y += obj.y;
        total.z += obj.z;
    }
    
    total.x /= self.recentFocusSquarePositions.count;
    total.y /= self.recentFocusSquarePositions.count;
    total.z /= self.recentFocusSquarePositions.count;
    
    return total;
    
//    return SCNVector3Zero;
}


- (CGFloat)normalizeWithAngle:(CGFloat)angle ref:(CGFloat)ref
{
    CGFloat normalized = angle;
    while ( fabs(normalized - ref) > (M_PI / 4) ) {
        
        if (angle > ref) {
            normalized -= M_PI / 2;
        } else {
            normalized += M_PI / 2;
        }
    }
    return normalized;
}

@end
